package cn.t.service.order;


import cn.t.constants.CommonConstants;
import cn.t.constants.ResponseError;
import cn.t.core.exception.BizException;
import cn.t.core.service.ServiceImpl;
import cn.t.enums.order.WorkLineStatusEnum;
import cn.t.enums.order.WorkStatusEnum;
import cn.t.model.order.WorkOrderDO;
import cn.t.model.order.WorkOrderDetailDO;
import cn.t.repository.order.WorkOrderRepository;
import cn.t.utils.DateUtil;
import cn.t.utils.RandomUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 工单表(WorkOrder)领域服务
 */
@Slf4j
@Service
@AllArgsConstructor
public class WorkOrderService extends ServiceImpl<WorkOrderDO, WorkOrderRepository> {

    private final RedissonClient redissonClient;
    private final WorkOrderDetailService workOrderDetailService;

    public List<WorkOrderDO> list(String workOrderSn, Date fromDate, Boolean expired, List<Integer> statusList) {
        WorkOrderDO queryParams = new WorkOrderDO();
        queryParams.setWorkOrderSn(workOrderSn);
        queryParams.setGmtCreatedStart(fromDate);
        queryParams.setExpired(expired);
        queryParams.setStatusList(statusList);
        return this.findByModel(queryParams, CommonConstants.ZERO, Integer.MAX_VALUE, null, null);
    }

    public List<WorkOrderDO> firstPage(Long firmId, Date fromDate, Integer size) {
        WorkOrderDO queryParams = new WorkOrderDO();
        queryParams.setFirmId(firmId);
        queryParams.setGmtCreatedStart(fromDate);
        queryParams.setAbnormalFlag(CommonConstants.ZERO);
        return this.findByModel(queryParams, CommonConstants.ZERO, size, "id", "desc");
    }

    public WorkOrderDO getWorkOrder(String workOrderSn) {
        List<WorkOrderDO> list = this.list(workOrderSn, null, null, null);
        return CollectionUtils.isEmpty(list) ? null : list.get(0);
    }

    public void updateWorkStatus(List<WorkOrderDetailDO> workOrderLineBeans, WorkOrderDO workOrderDO) {
        //检查所有行信息并调整头状态
        List<Integer> workOrderLineStatusList = workOrderLineBeans.stream().map(WorkOrderDetailDO::getStatus).collect(Collectors.toList());

        WorkStatusEnum workOrderLineStatus = WorkStatusEnum.PART_COMPLETED;

        if (workOrderLineStatusList.stream().allMatch(element -> element.equals(WorkLineStatusEnum.COMPLETED.getCode()))) {
            workOrderLineStatus = WorkStatusEnum.COMPLETED;
        }
        if (workOrderLineStatusList.stream().allMatch(element -> element.equals(WorkStatusEnum.WAIT_DO.getCode()))) {
            workOrderLineStatus = WorkStatusEnum.WAIT_DO;
        }
        workOrderDO.setStatus(workOrderLineStatus.getCode());
        if (workOrderLineBeans.size()>0) {
            boolean update =update(workOrderDO);
            boolean aBoolean1 = workOrderDetailService.updateBatchInfo(workOrderLineBeans);
            if (!aBoolean1 || !update) {
                throw new BizException(ResponseError.WORK_LINE_FAILED, ResponseError.WORK_LINE_FAILED.getName());
            }
        }
    }

    public boolean updateWorkOrder(WorkOrderDO workOrderDO) {
        return this.repository.updateWorkOrder(workOrderDO);
    }

    // 查询过期工单
    public List<WorkOrderDO> getWorkOrders(Boolean expired, List<Integer> statusList) {
        return this.list(null, null, expired, statusList);
    }

    public String getWorkOrderSn(String startStr) {

        String defaultSn = DateTimeFormatter.ofPattern("yyMMddHHmmss").format(LocalDateTime.now());
        Date today = DateUtil.currentDaily();

        RLock lock = redissonClient.getLock("openapi:getWorkOrderCount");
        try{
            lock.lock();
            List<WorkOrderDO> list = this.list(null, today, null, null);

            String todayStr = DateTimeFormatter.ofPattern("yyMMdd").format(LocalDate.now());
            Random random = RandomUtil.getRandomInstance();
            int i = random.nextInt(90) + 10;
            return startStr+ todayStr + String.format("%0" + 4 + "d", list.size())+i;
        }catch (Exception e){
            log.error("findToDayWorkOrderNumByOrgId出错:{}",e.getMessage());
        }finally {
            lock.unlock();
        }

        return startStr + defaultSn;
    }

    // 对接客户多了可升级为策略模式
    public void customizeWorkOrder(WorkOrderDO workOrderDO, String customerCode) {

        if (!StringUtils.hasText(customerCode)) {
            return;
        }

       if (CommonConstants.INDUSTRY_UNIFY_CUSTOMER_CODE.equals(customerCode)) {
            // 工单特殊处理
            workOrderDO.setRemark("" + DateUtil.getDateStr(new Date()));
            workOrderDO.setGmtExpire(DateUtil.afterTime(LocalDateTime.now(), CommonConstants.SEVEN, TimeUnit.DAYS));
        }
    }
}
